home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2007 December
/
PCWKCD1207B.iso
/
Blogowanie poza sfera
/
Flock 1.0 beta
/
flock-1.0RC3.en-US.win32.exe
/
flock
/
components
/
WebContentConverter.js
< prev
next >
Wrap
Text File
|
2007-10-18
|
24KB
|
764 lines
//@line 38 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/components/feeds/src/WebContentConverter.js"
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
function LOG(str) {
dump("*** " + str + "\n");
}
const WCCR_CONTRACTID = "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1";
const WCCR_CLASSID = Components.ID("{792a7e82-06a0-437c-af63-b2d12e808acc}");
const WCCR_CLASSNAME = "Web Content Handler Registrar";
const WCC_CLASSID = Components.ID("{db7ebf28-cc40-415f-8a51-1b111851df1e}");
const WCC_CLASSNAME = "Web Service Handler";
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
const TYPE_ANY = "*/*";
const PREF_CONTENTHANDLERS_AUTO = "browser.contentHandlers.auto.";
const PREF_CONTENTHANDLERS_BRANCH = "browser.contentHandlers.types.";
const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
const PREF_SELECTED_ACTION = "browser.feeds.handler";
const PREF_SELECTED_READER = "browser.feeds.handler.default";
const NS_ERROR_MODULE_DOM = 2152923136;
const NS_ERROR_DOM_SYNTAX_ERR = NS_ERROR_MODULE_DOM + 12;
function WebContentConverter() {
}
WebContentConverter.prototype = {
convert: function WCC_convert() { },
asyncConvertData: function WCC_asyncConvertData() { },
onDataAvailable: function WCC_onDataAvailable() { },
onStopRequest: function WCC_onStopRequest() { },
onStartRequest: function WCC_onStartRequest(request, context) {
var wccr =
Cc[WCCR_CONTRACTID].
getService(Ci.nsIWebContentConverterService);
wccr.loadPreferredHandler(request);
},
QueryInterface: function WCC_QueryInterface(iid) {
if (iid.equals(Ci.nsIStreamConverter) ||
iid.equals(Ci.nsIStreamListener) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
}
};
var WebContentConverterFactory = {
createInstance: function WCCF_createInstance(outer, iid) {
if (outer != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
return new WebContentConverter().QueryInterface(iid);
},
QueryInterface: function WCC_QueryInterface(iid) {
if (iid.equals(Ci.nsIFactory) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
}
};
function ServiceInfo(contentType, uri, name) {
this._contentType = contentType;
this._uri = uri;
this._name = name;
}
ServiceInfo.prototype = {
/**
* See nsIWebContentHandlerInfo
*/
get contentType() {
return this._contentType;
},
/**
* See nsIWebContentHandlerInfo
*/
get uri() {
return this._uri;
},
/**
* See nsIWebContentHandlerInfo
*/
get name() {
return this._name;
},
/**
* See nsIWebContentHandlerInfo
*/
getHandlerURI: function SI_getHandlerURI(uri) {
return this._uri.replace(/%s/gi, encodeURIComponent(uri));
},
/**
* See nsIWebContentHandlerInfo
*/
equals: function SI_equals(other) {
return this.contentType == other.contentType &&
this.uri == other.uri;
},
QueryInterface: function SI_QueryInterface(iid) {
if (iid.equals(Ci.nsIWebContentHandlerInfo) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
}
};
var WebContentConverterRegistrar = {
_contentTypes: { },
_protocols: { },
/**
* Track auto handlers for various content types using a content-type to
* handler map.
*/
_autoHandleContentTypes: { },
/**
* See nsIWebContentConverterService
*/
getAutoHandler:
function WCCR_getAutoHandler(contentType) {
contentType = this._resolveContentType(contentType);
if (contentType in this._autoHandleContentTypes)
return this._autoHandleContentTypes[contentType];
return null;
},
/**
* See nsIWebContentConverterService
*/
setAutoHandler:
function WCCR_setAutoHandler(contentType, handler) {
if (handler && !this._typeIsRegistered(contentType, handler.uri))
throw Cr.NS_ERROR_NOT_AVAILABLE;
contentType = this._resolveContentType(contentType);
this._setAutoHandler(contentType, handler);
var ps =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
var autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
if (handler)
autoBranch.setCharPref(contentType, handler.uri);
else if (autoBranch.prefHasUserValue(contentType))
autoBranch.clearUserPref(contentType);
ps.savePrefFile(null);
},
/**
* Update the internal data structure (not persistent)
*/
_setAutoHandler:
function WCCR__setAutoHandler(contentType, handler) {
if (handler)
this._autoHandleContentTypes[contentType] = handler;
else if (contentType in this._autoHandleContentTypes)
delete this._autoHandleContentTypes[contentType];
},
/**
* See nsIWebContentConverterService
*/
getWebContentHandlerByURI:
function WCCR_getWebContentHandlerByURI(contentType, uri) {
var handlers = this.getContentHandlers(contentType, { });
for (var i = 0; i < handlers.length; ++i) {
if (handlers[i].uri == uri)
return handlers[i];
}
return null;
},
/**
* See nsIWebContentConverterService
*/
loadPreferredHandler:
function WCCR_loadPreferredHandler(request) {
var channel = request.QueryInterface(Ci.nsIChannel);
var contentType = this._resolveContentType(channel.contentType);
var handler = this.getAutoHandler(contentType);
if (handler) {
request.cancel(Cr.NS_ERROR_FAILURE);
var webNavigation =
channel.notificationCallbacks.getInterface(Ci.nsIWebNavigation);
webNavigation.loadURI(handler.getHandlerURI(channel.URI.spec),
Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
null, null, null);
}
},
/**
* See nsIWebContentConverterService
*/
removeProtocolHandler:
function WCCR_removeProtocolHandler(protocol, uri) {
function notURI(currentURI) {
return currentURI != uri;
}
if (protocol in this._protocols)
this._protocols[protocol] = this._protocols[protocol].filter(notURI);
},
/**
* See nsIWebContentConverterService
*/
removeContentHandler:
function WCCR_removeContentHandler(contentType, uri) {
function notURI(serviceInfo) {
return serviceInfo.uri != uri;
}
if (contentType in this._contentTypes) {
this._contentTypes[contentType] =
this._contentTypes[contentType].filter(notURI);
}
},
/**
*
*/
_mappings: {
"application/rss+xml": TYPE_MAYBE_FEED,
"application/atom+xml": TYPE_MAYBE_FEED,
},
/**
* These are types for which there is a separate content converter aside
* from our built in generic one. We should not automatically register
* a factory for creating a converter for these types.
*/
_blockedTypes: {
"application/vnd.mozilla.maybe.feed": true,
},
/**
* Determines the "internal" content type based on the _mappings.
* @param contentType
* @returns The resolved contentType value.
*/
_resolveContentType:
function WCCR__resolveContentType(contentType) {
if (contentType in this._mappings)
return this._mappings[contentType];
return contentType;
},
_wrapString: function WCCR__wrapString(string) {
var supportsString =
Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
supportsString.data = string;
return supportsString;
},
_makeURI: function(aURL, aOriginCharset, aBaseURI) {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
return ioService.newURI(aURL, aOriginCharset, aBaseURI);
},
_confirmAddHandler: function WCCR__confirmAddHandler(contentType, title, uri, contentWindow) {
var args =
Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsArray);
var paramBlock =
Cc["@mozilla.org/embedcomp/dialogparam;1"].
createInstance(Ci.nsIDialogParamBlock);
// Used to tell the WCCR that the user chose to add the handler (rather
// than canceling).
const PARAM_SHOULD_ADD_HANDLER = 0;
paramBlock.SetInt(PARAM_SHOULD_ADD_HANDLER, 0);
args.AppendElement(paramBlock);
args.AppendElement(uri);
args.AppendElement(this._wrapString(title));
args.AppendElement(this._wrapString(contentType));
var typeType =
Cc["@mozilla.org/supports-PRInt32;1"].
createInstance(Ci.nsISupportsPRInt32);
typeType.data = 1;
args.AppendElement(typeType);
var browserContentWindow = contentWindow.top;
var browserWindow =
browserContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
// The tabbrowser implementation selects the associated tab when this
// is event is dispatched on the windoow.
var event = browserWindow.document.createEvent("Events");
event.initEvent("DOMWillOpenModalDialog", true, true);
browserContentWindow.dispatchEvent(event);
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
ww.openWindow(browserWindow,
"chrome://browser/content/feeds/addFeedReader.xul",
"", "modal,titlebar,centerscreen,dialog=yes", args);
var event = browserWindow.document.createEvent("Events");
event.initEvent("DOMModalDialogClosed", true, true);
browserContentWindow.dispatchEvent(event);
return paramBlock.GetInt(PARAM_SHOULD_ADD_HANDLER);
},
_checkForDuplicateContentType:
function WCCR__checkForDuplicateContentType(contentType, uri, title, contentWindow) {
contentType = this._resolveContentType(contentType);
if (this._typeIsRegistered(contentType, uri.spec)) {
// Show a special dialog for the feed case (XXXben - generalize at some
// point to allow other types to register specialized prompts).
this._confirmAddHandler(contentType, title, uri, contentWindow);
return false;
}
return true;
},
/**
* See nsIWebContentHandlerRegistrar
*/
registerProtocolHandler:
function WCCR_registerProtocolHandler(protocol, uriString, title, contentWindow) {
//@line 393 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/components/feeds/src/WebContentConverter.js"
},
/**
* See nsIWebContentHandlerRegistrar
* This is the web front end into the registration system, so a prompt to
* confirm the registration is provided, and the result is saved to
* preferences.
*/
registerContentHandler:
function WCCR_registerContentHandler(contentType, uriString, title, contentWindow) {
LOG("registerContentHandler(" + contentType + "," + uri + "," + title + ")");
try {
var uri = this._makeURI(uriString);
} catch (ex) {
// not supposed to throw according to spec
return;
}
// If the uri doesn't contain '%s', it won't be a good content handler
if (uri.spec.indexOf("%s") < 0)
throw NS_ERROR_DOM_SYNTAX_ERR;
// For security reasons we reject non-http(s) urls (see bug Bug 354316),
// we may need to revise this once we support more content types
if (uri.scheme != "http" && uri.scheme != "https")
throw("Permission denied to add " + uri.spec + "as a content handler");
// XXXben - for Firefox 2 we only support feed types
// XXX this should be a "security exception" according to spec, but that
// isn't defined yet.
contentType = this._resolveContentType(contentType);
if (contentType != TYPE_MAYBE_FEED)
return;
if (!this._checkForDuplicateContentType(contentType, uri, title, contentWindow) ||
!this._confirmAddHandler(contentType, title, uri, contentWindow))
return;
var spec = uri.spec;
this._registerContentHandler(contentType, spec, title);
this._saveContentHandlerToPrefs(contentType, spec, title);
},
/**
* Save Web Content Handler metadata to persistent preferences.
* @param contentType
* The content Type being handled
* @param uri
* The uri of the web service
* @param title
* The human readable name of the web service
*
* This data is stored under:
*
* browser.contentHandlers.type0 = content/type
* browser.contentHandlers.uri0 = http://www.foo.com/q=%s
* browser.contentHandlers.title0 = Foo 2.0alphr
*/
_saveContentHandlerToPrefs:
function WCCR__saveContentHandlerToPrefs(contentType, uri, title) {
var ps =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
var i = 0;
var typeBranch = null;
while (true) {
typeBranch =
ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + i + ".");
try {
typeBranch.getCharPref("type");
++i;
}
catch (e) {
// No more handlers
break;
}
}
if (typeBranch) {
typeBranch.setCharPref("type", contentType);
var pls =
Cc["@mozilla.org/pref-localizedstring;1"].
createInstance(Ci.nsIPrefLocalizedString);
pls.data = uri;
typeBranch.setComplexValue("uri", Ci.nsIPrefLocalizedString, pls);
pls.data = title;
typeBranch.setComplexValue("title", Ci.nsIPrefLocalizedString, pls);
ps.savePrefFile(null);
}
// Make the new handler the last-selected handler for the preview page
// and make sure the preview page is shown the next time a feed is visited
var pb = ps.getBranch(null);
pb.setCharPref(PREF_SELECTED_READER, "web");
pb.setCharPref(PREF_SELECTED_WEB, uri);
pb.setCharPref(PREF_SELECTED_ACTION, "ask");
},
/**
* Determines if there is a type with a particular uri registered for the
* specified content type already.
* @param contentType
* The content type that the uri handles
* @param uri
* The uri of the
*/
_typeIsRegistered: function WCCR__typeIsRegistered(contentType, uri) {
if (!(contentType in this._contentTypes))
return false;
var services = this._contentTypes[contentType];
for (var i = 0; i < services.length; ++i) {
// This uri has already been registered
if (services[i].uri == uri)
return true;
}
return false;
},
/**
* Gets a stream converter contract id for the specified content type.
* @param contentType
* The source content type for the conversion.
* @returns A contract id to construct a converter to convert between the
* contentType and *\/*.
*/
_getConverterContractID: function WCCR__getConverterContractID(contentType) {
const template = "@mozilla.org/streamconv;1?from=%s&to=*/*";
return template.replace(/%s/, contentType);
},
/**
* Update the content type -> handler map. This mapping is not persisted, use
* registerContentHandler or _saveContentHandlerToPrefs for that purpose.
* @param contentType
* The content Type being handled
* @param uri
* The uri of the web service
* @param title
* The human readable name of the web service
*/
_registerContentHandler:
function WCCR__registerContentHandler(contentType, uri, title) {
if (!(contentType in this._contentTypes))
this._contentTypes[contentType] = [];
// Avoid adding duplicates
if (this._typeIsRegistered(contentType, uri))
return;
this._contentTypes[contentType].push(new ServiceInfo(contentType, uri, title));
if (!(contentType in this._blockedTypes)) {
var converterContractID = this._getConverterContractID(contentType);
var cr = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
cr.registerFactory(WCC_CLASSID, WCC_CLASSNAME, converterContractID,
WebContentConverterFactory);
}
},
/**
* See nsIWebContentConverterService
*/
getContentHandlers:
function WCCR_getContentHandlers(contentType, countRef) {
countRef.value = 0;
if (!(contentType in this._contentTypes))
return [];
var handlers = this._contentTypes[contentType];
countRef.value = handlers.length;
return handlers;
},
/**
* See nsIWebContentConverterService
*/
resetHandlersForType:
function WCCR_resetHandlersForType(contentType) {
contentType = this._resolveContentType(contentType);
var ps =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
try {
var i = 0;
while (true) {
var handlerBranch =
ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + i + ".");
try {
if (handlerBranch.getCharPref("type") == contentType)
handlerBranch.resetBranch("");
var defaultBranch =
ps.getDefaultBranch(PREF_CONTENTHANDLERS_BRANCH + i + ".");
if (!this._registerContentHandlerWithBranch(defaultBranch))
break;
++i;
}
catch (e) {
}
}
}
catch (e) {
}
ps.savePrefFile(null);
},
/**
* Registers a handler from the settings on a branch
*/
_registerContentHandlerWithBranch: function(branch) {
/**
* Since we support up to six predefined readers, we need to handle gaps
* better, since the first branch with user-added values will be .6
*
* How we deal with that is to check to see if there's no prefs in the
* branch and stop cycling once that's true. This doesn't fix the case
* where a user manually removes a reader, but that's not supported yet!
*/
var vals = branch.getChildList("", {});
if (vals.length == 0)
return false;
try {
var type = branch.getCharPref("type");
var uri =
branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
var title =
branch.getComplexValue("title", Ci.nsIPrefLocalizedString).data;
this._registerContentHandler(type, uri, title);
}
catch (e) {
// do nothing, the next branch might have values
}
return true;
},
/**
* Load the auto handler, content handler and protocol tables from
* preferences.
*/
_init: function WCCR__init() {
var ps =
Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
try {
var i = 0;
while (true) {
var handlerBranch =
ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + (i++) + ".");
if (!this._registerContentHandlerWithBranch(handlerBranch))
break;
}
}
catch (e) {
// No content handlers yet, that's fine
//LOG("WCCR.init: There are no content handlers registered in preferences (benign).");
}
// We need to do this _after_ registering all of the available handlers,
// so that getWebContentHandlerByURI can return successfully.
try {
var autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
var childPrefs = autoBranch.getChildList("", { });
for (var i = 0; i < childPrefs.length; ++i) {
var type = childPrefs[i];
var uri = autoBranch.getCharPref(type);
if (uri) {
var handler = this.getWebContentHandlerByURI(type, uri);
this._setAutoHandler(type, handler);
}
}
}
catch (e) {
// No auto branch yet, that's fine
//LOG("WCCR.init: There is no auto branch, benign");
}
},
/**
* See nsIObserver
*/
observe: function WCCR_observe(subject, topic, data) {
var os =
Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
switch (topic) {
case "app-startup":
os.addObserver(this, "profile-after-change", false);
break;
case "profile-after-change":
os.removeObserver(this, "profile-after-change");
this._init();
break;
}
},
/**
* See nsIFactory
*/
createInstance: function WCCR_createInstance(outer, iid) {
if (outer != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
/**
* See nsIClassInfo
*/
getInterfaces: function WCCR_getInterfaces(countRef) {
var interfaces =
[Ci.nsIWebContentConverterService, Ci.nsIWebContentHandlerRegistrar,
Ci.nsIObserver, Ci.nsIClassInfo, Ci.nsIFactory, Ci.nsISupports];
countRef.value = interfaces.length;
return interfaces;
},
getHelperForLanguage: function WCCR_getHelperForLanguage(language) {
return null;
},
contractID: WCCR_CONTRACTID,
classDescription: WCCR_CLASSNAME,
classID: WCCR_CLASSID,
implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
flags: Ci.nsIClassInfo.DOM_OBJECT,
/**
* See nsISupports
*/
QueryInterface: function WCCR_QueryInterface(iid) {
if (iid.equals(Ci.nsIWebContentConverterService) ||
iid.equals(Ci.nsIWebContentHandlerRegistrar) ||
iid.equals(Ci.nsIObserver) ||
iid.equals(Ci.nsIClassInfo) ||
iid.equals(Ci.nsIFactory) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
},
};
var Module = {
QueryInterface: function M_QueryInterface(iid) {
if (iid.equals(Ci.nsIModule) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
},
getClassObject: function M_getClassObject(cm, cid, iid) {
if (!iid.equals(Ci.nsIFactory))
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
if (cid.equals(WCCR_CLASSID))
return WebContentConverterRegistrar;
throw Cr.NS_ERROR_NO_INTERFACE;
},
registerSelf: function M_registerSelf(cm, file, location, type) {
var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
cr.registerFactoryLocation(WCCR_CLASSID, WCCR_CLASSNAME, WCCR_CONTRACTID,
file, location, type);
var catman =
Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
catman.addCategoryEntry("app-startup", WCCR_CLASSNAME,
"service," + WCCR_CONTRACTID, true, true);
},
unregisterSelf: function M_unregisterSelf(cm, location, type) {
var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
cr.unregisterFactoryLocation(WCCR_CLASSID, location);
},
canUnload: function M_canUnload(cm) {
return true;
}
};
function NSGetModule(cm, file) {
return Module;
}
//@line 44 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/components/feeds/src/../../../../toolkit/content/debug.js"
var gTraceOnAssert = true;
/**
* This function provides a simple assertion function for JavaScript.
* If the condition is true, this function will do nothing. If the
* condition is false, then the message will be printed to the console
* and an alert will appear showing a stack trace, so that the (alpha
* or nightly) user can file a bug containing it. For future enhancements,
* see bugs 330077 and 330078.
*
* To suppress the dialogs, you can run with the environment variable
* XUL_ASSERT_PROMPT set to 0 (if unset, this defaults to 1).
*
* @param condition represents the condition that we're asserting to be
* true when we call this function--should be
* something that can be evaluated as a boolean.
* @param message a string to be displayed upon failure of the assertion
*/
function NS_ASSERT(condition, message) {
if (condition)
return;
var assertionText = "ASSERT: " + message + "\n";
//@line 72 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/components/feeds/src/../../../../toolkit/content/debug.js"
Components.util.reportError(assertionText);
return;
//@line 108 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/components/feeds/src/../../../../toolkit/content/debug.js"
}